home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / GraphicViewers / pCD / Source / hpcdtoppm.0.4 / format.c < prev    next >
C/C++ Source or Header  |  1993-03-23  |  8KB  |  354 lines

  1. /* hpcdtoppm (Hadmut's pcdtoppm) v0.4
  2. *  Copyright (c) 1992, 1993 by Hadmut Danisch (danisch@ira.uka.de).
  3. *  Permission to use and distribute this software and its
  4. *  documentation for noncommercial use and without fee is hereby granted,
  5. *  provided that the above copyright notice appear in all copies and that
  6. *  both that copyright notice and this permission notice appear in
  7. *  supporting documentation. It is not allowed to sell this software in 
  8. *  any way. This software is not public domain.
  9. */
  10.  
  11. #include "hpcdtoppm.h"
  12.  
  13. struct pcdquad { uBYTE len,highseq,lowseq,key;};
  14. struct pcdhqt  { uBYTE entries; struct pcdquad entry[256];};
  15. struct myhqt { unsigned long seq,mask,len; uBYTE key; };
  16.  
  17.  
  18. #define E ((unsigned long) 1)
  19.  
  20.  
  21. static void readhqtsub(quelle,ziel,anzahl)
  22.   struct pcdhqt *quelle;
  23.   struct myhqt *ziel;
  24.   int *anzahl;
  25.  {int i;
  26.   struct pcdquad *sub;
  27.   struct myhqt *help;
  28.   *anzahl=(quelle->entries)+1;
  29.  
  30.   for(i=0;i<*anzahl;i++)
  31.    {sub = (struct pcdquad *)(((uBYTE *)quelle)+1+i*sizeof(*sub));
  32.     help=ziel+i;
  33.  
  34.     help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
  35.     help->len = ((unsigned long) sub->len) +1;
  36.     help->key = sub->key;
  37.  
  38. #ifdef DEBUGhuff
  39.    fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
  40.           *anzahl,sbuffer,sub,((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
  41.           help->seq,help->len,sizeof(uBYTE));
  42. #endif
  43.  
  44.     if(help->len > 16) error(E_HUFF);
  45.  
  46.     help->mask = ~ ( (E << (32-help->len)) -1); 
  47.  
  48.   }
  49. #ifdef DEBUG
  50.   for(i=0;i<*anzahl;i++)
  51.    {help=ziel+i;
  52.     fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  53.         i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
  54.         help->seq & (~help->mask));
  55.    }
  56. #endif
  57.  
  58. }
  59.  
  60. #undef E
  61.  
  62.  
  63.  
  64.  
  65.  
  66. static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
  67. static int          myhufflen0=0,myhufflen1=0,myhufflen2=0;
  68.  
  69. void readhqt(w,h,n)
  70.   dim w,h;
  71.   int n;
  72.  {
  73.   uBYTE *ptr;
  74.  
  75.   melde("readhqt\n");
  76.   EREADBUF;
  77.   ptr = sbuffer;
  78.  
  79.   readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  80.  
  81.   if(n<2) return;
  82.   ptr+= 1 + 4* myhufflen0;
  83.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  84.  
  85.   if(n<3) return;
  86.   ptr+= 1 + 4* myhufflen1;
  87.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  88.  
  89. }
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97. #ifdef FASTHUFF
  98.  
  99. static struct myhqt *HTAB0[0x10000],*HTAB1[0x10000],*HTAB2[0x10000];
  100. static void inithuff(hlen,ptr,TAB)
  101.   int hlen;
  102.   struct myhqt *ptr,*TAB[];
  103.  {int i,n;
  104.   long seq,len;
  105.   struct myhqt *help;
  106.  
  107.   for(i=0;i<0x10000;i++) TAB[i]=0;
  108.  
  109.   for(n=0;n<hlen;n++)
  110.    {help=ptr+n;
  111.     seq=(help->seq)>>16;
  112.     len=help->len;
  113.  
  114.     for(i=0;i<(1<<(16-len));i++)
  115.       TAB[seq | i] = help;
  116.    }
  117.  }
  118. #endif
  119.  
  120.  
  121.  
  122.  
  123. static char *pn[]={"Luma Channel","Chroma1 Channel","Chroma2 Channel"};
  124.  
  125.  
  126. void decode(w,h,f,f1,f2,autosync)
  127.   dim w,h;
  128.   implane *f,*f1,*f2;
  129.   int autosync;
  130.  {int htlen,sum,do_inform,part;
  131.   unsigned long sreg,maxwidth;
  132.   unsigned int inh,n,zeile,segment,ident;
  133.   struct myhqt *hp;
  134.  
  135.   uBYTE *nptr;
  136.   uBYTE *lptr;
  137.  
  138. #define nextbuf  {  nptr=sbuffer;  EREADBUF; }
  139. #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  140. #define shiftout(n){ sreg<<=n; inh-=n; \
  141.                      while (inh<=24) \
  142.                       {checkbuf; \
  143.                        sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
  144.                        inh+=8;\
  145.                       }\
  146.                     }  
  147. #define issync     ((sreg & 0xffffff00) == 0xfffffe00) 
  148. #define brutesync  ((sreg & 0x00fff000) == 0x00fff000) 
  149. #define seeksync { while (!brutesync) shiftout(8); while (!issync) shiftout(1);}
  150.  
  151. #ifdef FASTHUFF
  152.   struct myhqt **HTAB;
  153.   HTAB=0;
  154.   inithuff(myhufflen0,myhuff0,HTAB0);
  155.   inithuff(myhufflen1,myhuff1,HTAB1);
  156.   inithuff(myhufflen2,myhuff2,HTAB2);
  157. #define SETHUFF0 HTAB=HTAB0;
  158. #define SETHUFF1 HTAB=HTAB1;
  159. #define SETHUFF2 HTAB=HTAB2;
  160. #define FINDHUFF(x) {x=HTAB[sreg>>16];}
  161.  
  162. #else
  163.  
  164.   int i;
  165.   struct myhqt *htptr;
  166.   htptr=0;
  167. #define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; }
  168. #define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; }
  169. #define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; }
  170. #define FINDHUFF(x)  {for(i=0, x=htptr;(i<htlen) && ((sreg & x ->mask)!= x->seq); i++,x++); \
  171.                       if(i>=htlen) x=0;}
  172. #endif
  173.  
  174.   melde("decode\n");
  175.  
  176.   if( f  && ((! f->im) || ( f->iheight < h  ) ||  (f->iwidth<w  ))) error(E_INTERN);
  177.   if( f1 && ((!f1->im) || (f1->iheight < h/2) || (f1->iwidth<w/2))) error(E_INTERN);
  178.   if( f2 && ((!f2->im) || (f2->iheight < h/2) || (f2->iwidth<w/2))) error(E_INTERN);
  179.  
  180.   htlen=sreg=maxwidth=0;
  181.   zeile=0;
  182.   nextbuf;
  183.   inh=32;
  184.   lptr=0;
  185.   part=do_inform=0;
  186.   shiftout(16);
  187.   shiftout(16);
  188.  
  189.   if(autosync) seeksync;
  190.  
  191.   n=0;
  192.   for(;;)
  193.    {
  194.     if (issync)
  195.      {shiftout(24);
  196.       ident=sreg>>16;
  197.       shiftout(16);
  198.  
  199.       zeile=(ident>>1) & 0x1fff;
  200.       segment=ident>>14;
  201.       if(do_inform) {fprintf(stderr,"Synchron mark found Line %u\n",zeile);do_inform=0;}
  202. #ifdef DEBUG
  203.       fprintf(stderr,"Id %4x Zeile: %6u Seg %3d Pix bisher: %5d  Position: %8lx+%5lx=%8x\n",
  204.           ident,zeile,segment,n,bufpos,nptr-sbuffer,bufpos+nptr-sbuffer);
  205. #endif
  206.  
  207.  
  208.       if(lptr && (n!=maxwidth)) 
  209.        {if(!do_rep)error(E_SEQ1);
  210.         else fprintf(stderr,"Line %u in %s : wrong length of last line (%u)\n",zeile,pn[part],n);
  211.        }
  212.       n=0;
  213.  
  214.       if(zeile==h) {RPRINT; return; }
  215.       if(zeile >h) error(E_SEQ2);
  216.  
  217.       switch(segment)
  218.        {
  219.         case 0: if((!f) && autosync) {seeksync; break;}
  220.                 if(!f) error(E_SEQ7);
  221.                 lptr=f->im + zeile*f->mwidth;
  222.                 maxwidth=f->iwidth;
  223.                 SETHUFF0;
  224.                 part=0;
  225.                 break;
  226.  
  227.         case 2: if((!f1) && autosync) {seeksync; break;}
  228.                 if(!f1) return;
  229.                 if(!f1) error(E_SEQ7);
  230.                 lptr=f1->im + (zeile>>1)*f1->mwidth;
  231.                 maxwidth=f1->iwidth;
  232.                 SETHUFF1;
  233.                 part=1;
  234.                 break;
  235.  
  236.         case 3: if((!f2) && autosync) {seeksync; break;}
  237.                 if(!f2) return;
  238.                 if(!f2) error(E_SEQ7);
  239.                 lptr=f2->im + (zeile>>1)*f2->mwidth;
  240.                 maxwidth=f2->iwidth;
  241.                 SETHUFF2;
  242.                 part=2;
  243.                 break;
  244.  
  245.         default:error(E_SEQ3);
  246.     }
  247.      }
  248.     else
  249.      {
  250.  
  251.  
  252.       if(!lptr)      error(E_SEQ6);
  253.       if(n>maxwidth) 
  254.         {
  255. #ifdef DEBUG
  256.          fprintf(stderr,"Register: %08lx Pos: %08lx\n",sreg,bufpos+nptr-sbuffer);
  257. #endif
  258.          if (!do_rep) error(E_SEQ4);
  259.          else { fprintf(stderr,"Missing synchron mark in %s line %u\n",pn[part],zeile);
  260.                 seeksync;
  261.                 do_inform=1;
  262.                 n=maxwidth;
  263.               }
  264.        }
  265.       else
  266.        {FINDHUFF(hp);
  267.         if(!hp) error(E_SEQ5);
  268.  
  269.         sum=((int)(*lptr)) + ((sBYTE)hp->key);
  270.         NORM(sum);
  271.         *(lptr++) = sum;
  272.  
  273.         n++; 
  274.         shiftout(hp->len);
  275.        }
  276.      }
  277.  
  278.    }
  279.  
  280.  
  281. #undef nextbuf  
  282. #undef checkbuf 
  283. #undef shiftout
  284. #undef issync
  285. #undef seeksync
  286.  
  287.  }
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296. enum ERRORS readplain(fpcd,w,h,l,c1,c2)
  297.   FILE *fpcd;
  298.   dim w,h;
  299.   implane *l,*c1,*c2;
  300.  {dim i;
  301.   uBYTE *pl=0,*pc1=0,*pc2=0;
  302.   melde("readplain\n");
  303.  
  304.   if(l)
  305.    { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) error(E_INTERN);
  306.      l->iwidth=w;
  307.      l->iheight=h;
  308.      pl=l->im;
  309.    }
  310.  
  311.   if(c1)
  312.    { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) error(E_INTERN);
  313.      c1->iwidth=w/2;
  314.      c1->iheight=h/2;
  315.      pc1=c1->im;
  316.    }
  317.  
  318.   if(c2)
  319.    { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) error(E_INTERN);
  320.      c2->iwidth=w/2;
  321.      c2->iheight=h/2;
  322.      pc2=c2->im;
  323.    }
  324.  
  325.   for(i=0;i<h/2;i++)
  326.    {
  327.     if(pl)
  328.      { 
  329.        if(fread(pl,w,1,fpcd)<1) return(E_READ);
  330.        pl+= l->mwidth;
  331.  
  332.        if(fread(pl,w,1,fpcd)<1) return(E_READ);
  333.        pl+= l->mwidth;
  334.      }
  335.     else SKIPr(2*w);
  336.      
  337.     if(pc1)
  338.      { if(fread(pc1,w/2,1,fpcd)<1) return(E_READ);
  339.        pc1+= c1->mwidth;
  340.      }
  341.     else SKIPr(w/2);
  342.      
  343.     if(pc2)
  344.      { if(fread(pc2,w/2,1,fpcd)<1) return(E_READ);
  345.        pc2+= c2->mwidth;
  346.      }
  347.     else SKIPr(w/2);
  348.  
  349.  
  350.    }
  351.   RPRINT;
  352.   return E_NONE;
  353.  }
  354.